/*
 * Copyright (c) 2018 Hitevision
 */

package tw.com.hitevision.whiteboard.android.storage;

import android.content.Context;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;

import androidx.annotation.Nullable;
import tw.com.hitevision.whiteboard.android.util.GlideApp;

public class FileHandler extends Handler {
    private static final String TAG = FileHandler.class.getSimpleName();

    private static final int MSG_WHAT_SAVE_TO_FILE = 1;
    private static final int MSG_WHAT_DELETE_FILE = 2;
    private static final int MSG_WHAT_COPY_TO_FILE = 3;
    private static final int MSG_WHAT_SAVE_TO_CACHE = 4;
    private static final int MSG_WHAT_SAVE_TO_INTERNAL = 5;

    private static final String DATA_IMAGE = "dataImage";
    private static final String DATA_FILE_NAME = "dataFileName";
    private static final String DATA_MOUNT_PATH = "dataMountPath";
    private static final String DATA_DO_RECYCLE = "dataDoRecycle";
    private static final String DATA_TARGET_FILE_NAME = "dataTargetFileName";

    private final Context context;
    private final FileHelper fileHelper;

    public FileHandler(Context context, Looper looper) {
        super(looper);

        this.context = context.getApplicationContext();
        fileHelper = FileHelper.getInstance(context);
    }

    public void sendSaveImageMessage(Bitmap image, String fileName) {
        sendSaveImageMessage(image, fileName, null, false);
    }

    public void sendSaveCacheImageMessage(Bitmap image, String fileName) {
        if (image == null || fileName == null) {
            return;
        }

        final Bundle b = new Bundle();
        b.putParcelable(DATA_IMAGE, image);
        b.putString(DATA_FILE_NAME, fileName);

        final Message msg = Message.obtain(this, MSG_WHAT_SAVE_TO_CACHE);
        msg.setData(b);

        sendMessage(msg);
    }

    public void sendSaveImageMessage(Bitmap image, String fileName, String mountPath) {
        sendSaveImageMessage(image, fileName, mountPath, false);
    }

    public void sendSaveImageMessage(Bitmap image, String fileName, @Nullable String mountPath,
                                     boolean doRecycle) {
        if (image == null || fileName == null) {
            return;
        }

        final Bundle b = new Bundle();
        b.putParcelable(DATA_IMAGE, image);
        b.putString(DATA_FILE_NAME, fileName);
        b.putString(DATA_MOUNT_PATH, mountPath);
        b.putBoolean(DATA_DO_RECYCLE, doRecycle);

        final Message msg = Message.obtain(this, MSG_WHAT_SAVE_TO_FILE);
        msg.setData(b);

        sendMessage(msg);
    }

    public void sendCopyPreviewMessage(String fileName, @Nullable String mountPath,
                                       @Nullable String targetFileName) {
        final Bundle b = new Bundle();
        b.putString(DATA_FILE_NAME, fileName);
        b.putString(DATA_MOUNT_PATH, mountPath);
        b.putString(DATA_TARGET_FILE_NAME, targetFileName);

        final Message msg = Message.obtain(this, MSG_WHAT_COPY_TO_FILE);
        msg.setData(b);

        sendMessage(msg);
    }

    public void sendDeleteImageMessage(String fileName) {
        if (fileName == null) {
            return;
        }

        final Message msg = Message.obtain(this, MSG_WHAT_DELETE_FILE);
        msg.obj = fileName;

        sendMessage(msg);
    }

    public void sendSaveImageToInternal(Bitmap bitmap) {
        if (bitmap != null) {
            final Bundle b = new Bundle();
            b.putParcelable(DATA_IMAGE, bitmap);

            final Message msg = Message.obtain(this, MSG_WHAT_SAVE_TO_INTERNAL);
            msg.setData(b);

            sendMessage(msg);
        }
    }

    @Override
    public void handleMessage(Message msg) {
        switch (msg.what) {
            case MSG_WHAT_SAVE_TO_FILE: {
                final Bundle b = msg.getData();
                final Bitmap image = b.getParcelable(DATA_IMAGE);
                final String fileName = b.getString(DATA_FILE_NAME);
                final String mountPath = b.getString(DATA_MOUNT_PATH);
                final boolean doRecycle = b.getBoolean(DATA_DO_RECYCLE, false);

                if (image != null) {
                    fileHelper.saveToFile(context, image, fileName, mountPath);

                    if (doRecycle) {
                        b.remove(DATA_IMAGE);
                        GlideApp.get(context)
                                .getBitmapPool()
                                .put(image);
                    }
                }
                break;
            }
            case MSG_WHAT_DELETE_FILE: {
                final String fileName = (String) msg.obj;
                fileHelper.delete(context, fileName);
                break;
            }
            case MSG_WHAT_COPY_TO_FILE: {
                final Bundle b = msg.getData();
                final String fileName = b.getString(DATA_FILE_NAME);
                final String mountPath = b.getString(DATA_MOUNT_PATH);
                final String targetFileName = b.getString(DATA_TARGET_FILE_NAME);

                if (fileName != null) {
                    fileHelper.copyPreviewToFile(context, fileName, mountPath, targetFileName);
                }
                break;
            }
            case MSG_WHAT_SAVE_TO_CACHE: {
                final Bundle b = msg.getData();
                final Bitmap image = b.getParcelable(DATA_IMAGE);
                final String fileName = b.getString(DATA_FILE_NAME);
                if (image != null) {
                    fileHelper.writeToCache(context, fileName, image);
                }
                break;
            }
            case MSG_WHAT_SAVE_TO_INTERNAL: {
                final Bundle b = msg.getData();
                final Bitmap image = b.getParcelable(DATA_IMAGE);

                if (image != null) {
                    fileHelper.saveFileToInternalStorage(image);
                }

                break;
            }

        }
    }

    private static void log(String msg) {
        Log.d(TAG, msg);
    }
}
